namespace AnalyStock.GrapImage;

//面板的移动事件通用处理
public static class ElementMouseAction
{
    public static void InitializeMouseDarg(this FrameworkElement element, FrameworkElement parent)
    {
        _ = new ElementDargMove(element, parent);
    }

    public class ElementDargMove
    {
        private readonly Thickness _iniThickness;
        private readonly FrameworkElement _parentElement;
        private bool _isMouseDown;
        private Point _mouseDownPosition;
        private double _moveWidth_Boundary, _moveHeight_Boundary;

        public ElementDargMove(FrameworkElement element, FrameworkElement parent)
        {
            _parentElement = parent;
            _iniThickness = element.Margin;
            element.MouseLeftButtonDown += Element_MouseLeftButtonDown;
            element.MouseLeftButtonUp += Element_MouseLeftButtonUp;
            element.MouseMove += Element_MouseMove;
            parent.SizeChanged += (s, e) => element.Margin = _iniThickness;
        }

        private void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isMouseDown)
            {
                //确定新的margin位置
                var _currEle = sender as FrameworkElement;
                var _pos = e.GetPosition(_parentElement);
                var (_left, _top, _right, _bottom) = (
                    _pos.X - _mouseDownPosition.X + _currEle.Margin.Left,
                    _pos.Y - _mouseDownPosition.Y + _currEle.Margin.Top,
                    _mouseDownPosition.X - _pos.X + _currEle.Margin.Right,
                    _mouseDownPosition.Y - _pos.Y + _currEle.Margin.Bottom);
                //重新确认margin值，实现移动
                _currEle.Margin = new Thickness(
                    XMovePos_Boundary(_left), YMovePos_Boundary(_top),
                    XMovePos_Boundary(_right), YMovePos_Boundary(_bottom));
                _mouseDownPosition = e.GetPosition(_parentElement);
                e.Handled = true; //不允许鼠标事件传递
            }
            
            double XMovePos_Boundary(double xPos) =>
                xPos < 0 ? 0 : xPos >= _moveWidth_Boundary ? _moveWidth_Boundary : xPos;
            double YMovePos_Boundary(double yPos) =>
                yPos < 0 ? 0 : yPos >= _moveHeight_Boundary ? _moveHeight_Boundary : yPos;

        }

        private void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var _currEle = sender as FrameworkElement;
            _moveWidth_Boundary = _parentElement.ActualWidth - _currEle.ActualWidth - 5.0;
            _moveHeight_Boundary = _parentElement.ActualHeight - _currEle.ActualHeight - 5.0;
            _isMouseDown = true;
            _mouseDownPosition = e.GetPosition(_parentElement);
            _currEle.Cursor = Cursors.Hand;
            _currEle.CaptureMouse();
            e.Handled = true;
        }

        private void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (_isMouseDown)
            {
                var _currEle = sender as FrameworkElement;
                _isMouseDown = false;
                _currEle.ReleaseMouseCapture();
                _currEle.Cursor = Cursors.Arrow;
                e.Handled = true;
            }
        }
    }
}